package com.suiwei.advanced.collection;

import com.suiwei.base.common.Student;
import com.suiwei.base.common.Student2;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
import org.junit.jupiter.api.Test;

//set接口：存取无序，没有索引，不可以存储重复数据
//实现类：TreeSet，HashSet，LinkedHashSet
public class SetDemo {
    /**
     * 底层红黑树：元素是排好序的，并且去重
     */
    @Test
    void treeSetTest() {
        TreeSet ts = new TreeSet();
        ts.add("a");
        ts.add("c");
        ts.add("c");
        ts.add("b");
        System.out.println(ts);//[a, b, c]

        TreeSet ts3 = new TreeSet();
        //Student2实现了自然排序
        ts3.add(new Student2(1,"张三"));
        ts3.add(new Student2(2,"李四"));
        System.out.println(ts3);

        TreeSet ts2 = new TreeSet();
        // 每次调用add方法的时候，内部会调用compareTo方法，所以添加的对象必须实现Comparable接口（实现了接口才会有自然排序）
        // 否则报错：java.lang.ClassCastException: com.suiwei.base.common.Student cannot be cast to java.lang.Comparable
        ts2.add(new Student("1", "张三"));
        System.out.println(ts2);

        //比较器排序：TreeSet对象的构造方法传入Comparator对象
        TreeSet ts4 = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //修改规则
                return 0;
            }
        });
    }
    //底层数据结构是哈希表，无序，去重
    @Test
    void  hashSetTest(){
        //去重
        HashSet hs = new HashSet();
        hs.add("a");
        hs.add("a");
        System.out.println(hs);//[a]

        //去重
        //必须重写类的hashCode() 和 equals()：HashSet 使用对象的 hashCode() 和 equals() 方法来确定是否两个对象相等以便去重
        //add方法先调用hashcode()方法，算出索引位置，如果该位置没有元素，则直接存入，如果有元素，则调用equals()方法比较内容，相等则不存储（去重）
        HashSet<Student2> hs2 = new HashSet<Student2>();
        hs2.add(new Student2(1,"张三"));
        hs2.add(new Student2(1,"张三"));
        System.out.println(hs2);
  }
    //有序、去重
    //底层数据结构依然是哈希表，只是每个元素又额外的多了一个双向链表的机制记录存储的顺序
    @Test
    void  LinkedHashSetTest(){
        //去重，并且排序
        LinkedHashSet<String> lhs = new LinkedHashSet<>();
        lhs.add("b");
        lhs.add("c");
        lhs.add("b");
        lhs.add("a");
        System.out.println(lhs);//[b, c, a]
  }
}
